#pragma once

#include <memory>
#include <unordered_map>
#include <functional>

#include "mainwindow.h"
#include "network_message.h"
#include "minesweeprwidget.h"
#include "mainwidget.h"
#include "game_widget.h"

class tcp_client;
class UserLoginWidget;
class UserRegisterWidget;
class MainWindow;

/* 单例类，处理服务器端发送来的网络消息 */
class network_message_handler {
public:
    using network_message_handler_func =
        std::function<int(network_message_handler *, std::shared_ptr<tcp_client>, const network_message&)>;

    static network_message_handler& get_instance() {
        static network_message_handler instance;
        return instance;
    }

    int handle_message(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);

    void setMineSweeprWidget(std::shared_ptr<MineSweeprWidget> mine_sweeper_wgt)
    {
        mine_sweeper_wgt_ = mine_sweeper_wgt;
    }

    void setUserLoginWidget(std::shared_ptr<UserLoginWidget> user_login_wgt)
    {
        user_login_wgt_ = user_login_wgt;
    }

    void setUserRegisterWidget(std::shared_ptr<UserRegisterWidget> user_register_wgt)
    {
        user_register_wgt_ = user_register_wgt;
    }

    // void setMainWindow(MainWindow *mw)
    // {
    //     mainwindow_ = mw;
    // }

    void setMainWidget(std::shared_ptr<MainWidget> main_widget)
    {
        main_widget_ = main_widget;
    }

    void setGameWidget(std::shared_ptr<GameWidget> game_widget)
    {
        game_widget_ = game_widget;
    }


private:
    network_message_handler()
    {
        init_message_handler_map();
    }

    network_message_handler(const network_message_handler&) = delete;
    network_message_handler& operator=(const network_message_handler&) = delete;

    int message_handler_heart_beat(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_user_login(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_user_register(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_left_button_clicked(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_user_start_matching(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_user_stop_matching(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_game_init(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);
    int message_handler_game_over(std::shared_ptr<tcp_client> tcp_client, const network_message& msg);

    void register_message_handler(uint32_t msg_type, network_message_handler_func handler)
    {
        msg_handler_map_[msg_type] = handler;
    }

    /* 在此处添加消息类型和消息处理方式的映射关系 */
    void init_message_handler_map();

    /* data member */
    std::unordered_map<uint32_t, network_message_handler_func> msg_handler_map_;
    std::weak_ptr<MineSweeprWidget> mine_sweeper_wgt_;
    std::weak_ptr<UserLoginWidget> user_login_wgt_;
    std::weak_ptr<UserRegisterWidget> user_register_wgt_;
    std::shared_ptr<MainWidget> main_widget_;
    std::shared_ptr<GameWidget> game_widget_;
    // MainWindow *mainwindow_;
};
